using Reflector.CodeModel;

namespace LanguageWriterHelper
{
    public class ILVisitor : VisitorBase
    {
    
        public void Visit(ICatchClause value)
        {
            if (value == null)
                return;

            WriteStartElement("ICatchClause");

            WriteStartElement("Body");
            Manager.StatementVisitor.Visit(value.Body);
            WriteEndElement();

            WriteStartElement("Condition");
            Manager.ExpressionVisitor.Visit(value.Condition);
            WriteEndElement();

            WriteStartElement("Variable");
            Visit(value.Variable);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(ICatchClauseCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("ICatchClauseCollection");
            
            foreach (ICatchClause cc in value)
            {
                Visit(cc);
            }

            WriteEndElement();
        }
                
        public void Visit(IComment value)
        {
            if (value == null)
                return;

            WriteStartElement("IComment");
            
            WriteElement("Text", value.Text);

            WriteEndElement();
        }

        
        public void Visit(IConditionCase value)
        {
            if (value == null)
                return;

            WriteStartElement("IConditionCase");

            WriteStartElement("Body");
            Manager.StatementVisitor.Visit(value.Body);
            WriteEndElement();

            WriteStartElement("Condition");
            Manager.ExpressionVisitor.Visit(value.Condition);
            WriteEndElement();

            WriteEndElement();
        }
               
        public void Visit(IConstructorDeclaration value)
        {
            if (value == null)
                return;

            WriteStartElement("IConstructorDeclaration");

            Manager.MetadataVisitor.Visit((IMethodDeclaration)value);

            WriteStartElement("Initializer");
            Manager.ExpressionVisitor.Visit(value.Initializer);
            WriteEndElement();

            WriteEndElement();
        }              
        
        public void Visit(IDefaultCase value)
        {
            if (value == null)
                return;

            WriteStartElement("IDefaultCase");
            
            WriteStartElement("Body");
            Manager.StatementVisitor.Visit(value.Body);
            WriteEndElement();

            WriteEndElement();
        }
                       
        public void Visit(IExceptionHandler value)
        {
            if (value == null)
                return;

            WriteStartElement("IExceptionHandler");

            WriteElement("FilterOffset", value.FilterOffset.ToString());
            WriteElement("HandlerLength", value.HandlerLength.ToString());
            WriteElement("HandlerOffset", value.HandlerOffset.ToString());
            WriteElement("TryLength", value.TryLength.ToString());
            WriteElement("TryOffset", value.TryOffset.ToString());
            WriteElement("Type", value.Type.ToString());

            WriteStartElement("CatchType");
            Manager.MetadataVisitor.Visit(value.CatchType);
            WriteEndElement();
            
            WriteEndElement();
        }

        public void Visit(IExceptionHandlerCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IExceptionHandlerCollection");

            foreach (IExceptionHandler eh in value)
            {
                Visit(eh);
            }

            WriteEndElement();
        }
                
        public void Visit(IFromClause value)
        {
            if (value == null)
                return;

            WriteStartElement("IFromClause");

            WriteStartElement("Expression");
            Manager.ExpressionVisitor.Visit(value.Expression);
            WriteEndElement();

            WriteStartElement("Variable");
            Visit(value.Variable);
            WriteEndElement();
            
            WriteEndElement();
        }

        public void Visit(IFunctionPointer value)
        {
            if (value == null)
                return;

            WriteStartElement("IFunctionPointer");

            Manager.MetadataVisitor.Visit((IMethodSignature)value);

            WriteEndElement();
        }
                
        public void Visit(IGroupOperation value)
        {
            if (value == null)
                return;

            WriteStartElement("IGroupOperation");

            WriteStartElement("Item");
            Manager.ExpressionVisitor.Visit(value.Item);
            WriteEndElement();

            WriteStartElement("Key");
            Manager.ExpressionVisitor.Visit(value.Key);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(IInstruction value)
        {
            if (value == null)
                return;

            WriteStartElement("IInstruction");
            
            WriteElement("Code", value.Code.ToString());
            WriteElement("Offset", value.Offset.ToString());
            WriteElement("Value", (value.Value == null) ? "null" : value.Value.ToString());

            WriteEndElement();
        }

        public void Visit(IInstructionCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IInstructionCollection");
            
            foreach (IInstruction i in value)
            {
                Visit(i);
            }

            WriteEndElement();
        }

        public void Visit(IJoinClause value)
        {
            if (value == null)
                return;

            WriteStartElement("IJoinClause");

            WriteStartElement("Equality");
            Manager.ExpressionVisitor.Visit(value.Equality);
            WriteEndElement();

            WriteStartElement("In");
            Manager.ExpressionVisitor.Visit(value.In);
            WriteEndElement();

            WriteStartElement("Into");
            Visit(value.Into);
            WriteEndElement();

            WriteStartElement("On");
            Manager.ExpressionVisitor.Visit(value.On);
            WriteEndElement();

            WriteStartElement("Variable");
            Visit(value.Variable);
            WriteEndElement();            

            WriteEndElement();
        }

        public void Visit(ILetClause value)
        {
            if (value == null)
                return;

            WriteStartElement("ILetClause");

            WriteStartElement("Expression");
            Manager.ExpressionVisitor.Visit(value.Expression);
            WriteEndElement();

            WriteStartElement("Variable");
            Visit(value.Variable);
            WriteEndElement();
            
            WriteEndElement();
        }

        public void Visit(IMethodBody value)
        {
            if (value == null)
                return;

            WriteStartElement("IMethodBody");

            WriteElement("MaxStack", value.MaxStack.ToString());
            WriteElement("InitializeLocalVariables", value.InitializeLocalVariables.ToString());

            WriteStartElement("ExceptionHandlers");
            Manager.ILVisitor.Visit(value.ExceptionHandlers);
            WriteEndElement();

            WriteStartElement("Instructions");
            Visit(value.Instructions);
            WriteEndElement();

            WriteStartElement("LocalVariables");
            Visit(value.LocalVariables);
            WriteEndElement();
            
            WriteEndElement();
        }

        public void Visit(IOrderClause value)
        {
            if (value == null)
                return;

            WriteStartElement("IOrderClause");

            WriteElement("Direction", value.Direction.ToString());

            WriteStartElement("Expression");
            Manager.ExpressionVisitor.Visit(value.Expression);
            WriteEndElement();
            
            WriteEndElement();
        }
               
        public void Visit(IQueryBody value)
        {
            if (value == null)
                return;

            WriteStartElement("IQueryBody");

            WriteStartElement("Clauses");
            Visit(value.Clauses);
            WriteEndElement();

            WriteStartElement("Continuation");
            Visit(value.Continuation);
            WriteEndElement();

            WriteStartElement("Operation");
            Visit(value.Operation);
            WriteEndElement();
            
            WriteEndElement();
        }

        public void Visit(IQueryClause value)
        {
            if (value == null)
                return;

            Visit(value as IFromClause);
            Visit(value as IJoinClause);
            Visit(value as ILetClause);
            Visit(value as IOrderClause);
            Visit(value as IWhereClause);
        }

        public void Visit(IQueryClauseCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IQueryClauseCollection");

            foreach (IQueryClause qc in value)
            {
                Visit(qc);
            }
            
            WriteEndElement();
        }

        public void Visit(IQueryContinuation value)
        {
            if (value == null)
                return;

            WriteStartElement("IQueryContinuation");

            WriteStartElement("Body");
            Visit(value.Body);
            WriteEndElement();

            WriteStartElement("Variable");
            Visit(value.Variable);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(IQueryOperation value)
        {
            if (value == null)
                return;

            Visit(value as IGroupOperation);
            Visit(value as ISelectOperation);
        }
                 
        public void Visit(ISelectOperation value)
        {
            if (value == null)
                return;

            WriteStartElement("ISelectOperation");

            WriteStartElement("Expression");
            Manager.ExpressionVisitor.Visit(value.Expression);
            WriteEndElement();
            
            WriteEndElement();
        }     

        public void Visit(IStringCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IStringCollection");

            foreach (string s in value)
            {
                WriteElement("String", s);
            }

            WriteEndElement();
        }

        public void Visit(ISwitchCase value)
        {
            if (value == null)
                return;

            WriteStartElement("ISwitchCase");

            WriteStartElement("Body");
            Manager.StatementVisitor.Visit(value.Body);
            WriteEndElement();

            WriteEndElement();
        }

        public void Visit(ISwitchCaseCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("ISwitchCaseCollection");
            
            foreach (ISwitchCase sc in value)
            {
                Visit(sc);
            }
                        
            WriteEndElement();
        }
              
        public void Visit(IVariableDeclaration value)
        {
            if (value == null)
                return;

            WriteStartElement("IVariableDeclaration");
            
            WriteElement("Identifier", value.Identifier.ToString());
            WriteElement("Name", value.Name);
            WriteElement("Pinned", value.Pinned.ToString());
            WriteElement("Symbol", value.Symbol.ToString());

            WriteStartElement("VariableType");
            Manager.MetadataVisitor.Visit(value.VariableType);
            WriteEndElement();
            
            WriteEndElement();
        }
        
        public void Visit(IVariableDeclarationCollection value)
        {
            if (value == null || value.Count == 0)
                return;

            WriteStartElement("IVariableDeclarationCollection");

            foreach (IVariableDeclaration vd in value)
            {
                Visit(vd);
            }
            
            WriteEndElement();
        }

        public void Visit(IVariableReference value)
        {
            if (value == null)
                return;

            WriteStartElement("IVariableReference");

            Visit(value.Resolve());
                        
            WriteEndElement();
        }
        
        public void Visit(IWhereClause value)
        {
            if (value == null)
                return;

            WriteStartElement("IWhereClause");

            WriteStartElement("Expression");
            Manager.ExpressionVisitor.Visit(value.Expression);
            WriteEndElement();
            
            WriteEndElement();
        }
        
        
    }
}
